﻿#include "mainwindow.h"
#include<QGraphicsView>
#include<QMenu>
#include<QMenuBar>
#include<QGraphicsEllipseItem>
#include"flashitem.h"
#include"startiterm.h"
#include<QGraphicsItemAnimation>
#include<QTimeLine>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    createActions();
    createMenus();
    scene=new QGraphicsScene;
    scene->setSceneRect(-200,-200,400,400);
    initScene();
    QGraphicsView *view=new QGraphicsView;
    view->setScene(scene);//将scene设置为view,将图像可见
    view->setMinimumSize(400,400);
    view->show();
    setCentralWidget(view);
    resize(550,450);
    setWindowTitle(tr("Graphics Items"));
}

MainWindow::~MainWindow() {}



void MainWindow::createActions()//创建主窗体的所有动作
{
    newACt=new QAction(tr("新建"),this);
    clearAct=new QAction(tr("清除"),this);
    exitAct=new QAction(tr("退出"),this);

    addEllipseItemAct=new QAction(tr("加入 椭圆"),this);
    addPolygonItemAct=new QAction(tr("加入 多边形"),this);
    addTextItemAct=new QAction(tr("加入 文字"),this);
    addRectItemAct=new QAction(tr("加入 长方形"),this);
    addAlphaItemAct=new QAction(tr("加入 透明图片"),this);
    addFlashItemAct=new QAction(tr("加入闪烁圆"),this);
    addAnimItemAct=new QAction(tr("加入星星"),this);

    connect(newACt,SIGNAL(triggered(bool)),this,SLOT(slotNew()));
    connect(clearAct,SIGNAL(triggered(bool)),this,SLOT(slotClear()));
    connect(exitAct,SIGNAL(triggered(bool)),this,SLOT(close()));
    connect(addEllipseItemAct,SIGNAL(triggered(bool)),this,SLOT(slotAddEllipseItem()));
    connect(addPolygonItemAct,SIGNAL(triggered(bool)),this,SLOT(slotAddPolygonItem()));
    connect(addTextItemAct,SIGNAL(triggered(bool)),this,SLOT(slotAddTextItem()));
    connect(addRectItemAct,SIGNAL(triggered(bool)),this,SLOT(slotAddRectItem()));
    connect(addAlphaItemAct,SIGNAL(triggered(bool)),this,SLOT(slotAddAlphaItem()));
    connect(addFlashItemAct,SIGNAL(triggered(bool)),this,SLOT(slotAddFlashItem()));
    connect(addAnimItemAct,SIGNAL(triggered(bool)),this,SLOT(slotAddAnimItemAct()));
}
void MainWindow::createMenus()//创建主窗体的菜单栏
{
    QMenu *fileMenu=menuBar()->addMenu(tr("文件"));
    fileMenu->addAction(newACt);
    fileMenu->addAction(clearAct);
    fileMenu->addSeparator();
    fileMenu->addAction(exitAct);

    QMenu *itemsMenu=menuBar()->addMenu(tr("元素"));
    itemsMenu->addAction(addEllipseItemAct);
    itemsMenu->addAction(addPolygonItemAct);
    itemsMenu->addAction(addTextItemAct);
    itemsMenu->addAction(addRectItemAct);
    itemsMenu->addAction(addAlphaItemAct);
    itemsMenu->addAction(addFlashItemAct);
    itemsMenu->addAction(addAnimItemAct);
}

void MainWindow::initScene()//初始化场景
{
    int i;
    for(i=0;i<3;i++)
    {
        slotAddEllipseItem();
    }
    for(i=0;i<3;i++)
    {
        slotAddTextItem();
    }
    for(i=0;i<3;i++)
    {
        slotAddAlphaItem();
    }
    for(i= 0;i< 3;i++) {
        slotAddFlashItem();
    }
    for(i= 0;i< 3;i++) {
        slotAddAnimItemAct();
    }
}

void MainWindow::slotNew()//新建一个显示窗体
{
    slotClear();
    initScene();
    MainWindow *newwin=new MainWindow;
    newwin->show();
}
void MainWindow::slotClear()//清除场景中所有的图元
{
    QList<QGraphicsItem*>listItem=scene->items();
    while(!listItem.empty())
    {
        scene->removeItem(listItem.at(0));
        listItem.removeAt(0);
    }
}
void MainWindow::slotAddEllipseItem()//加入椭圆形图元
{
    QGraphicsEllipseItem *item=new QGraphicsEllipseItem(QRectF(0,0,80,60));
    item->setPen(Qt::NoPen);
    item->setBrush(QColor(rand()%256,rand()%256,rand()%256));
    item->setFlag(QGraphicsItem::ItemIsMovable);//用来设置图形项（Graphics Item）的标志（flags）以使其可移动。
    scene->addItem(item);
    item->setPos((rand()%int(scene->sceneRect().width()))-200,(rand()%int(scene->sceneRect().height()))-200);
}

void MainWindow::slotAddPolygonItem()//加入多边形图元
{
    QVector<QPoint>v;
    v<<QPoint(30,-15)<<QPoint(0,-30)<<QPoint(-30,-15)<<QPoint(-30,15)<<QPoint(0,30)<<QPoint(30,15);
   //QPolygonF 是 Qt 中用于表示浮点精度多边形的类。它是 QPolygon 的一种特化，QPolygon 用于表示整数精度的多边形。
   // QPolygonF 提供了一种方便的方式来定义和操作浮点精度的多边形。它可以存储多个 QPointF 对象，
   // 每个 QPointF 对象表示多边形的一个顶点，因此可以表示任意形状的多边形。
    QGraphicsPolygonItem *item=new QGraphicsPolygonItem(QPolygonF(v));
    item->setBrush(QColor(rand()%256,rand()%256,rand()%256));
    item->setFlag(QGraphicsItem::ItemIsMovable);//用来设置图形项（Graphics Item）的标志（flags）以使其可移动。
    scene->addItem(item);
    item->setPos((rand()%int(scene->sceneRect().width()))-200,(rand()%int(scene->sceneRect().height()))-200);
}
void MainWindow::slotAddTextItem()//文字图元
{
    QFont font("Times",16);
    QGraphicsTextItem *item=new QGraphicsTextItem("Hello Qt");
    item->setFont(font);
    item->setFlag(QGraphicsItem::ItemIsMovable);
    scene->addItem(item);
    item->setPos((rand()%int(scene->sceneRect().width()))-200,(rand()%int(scene->sceneRect().height()))-200);
}
void MainWindow::slotAddRectItem()//长方形图元
{
    QGraphicsRectItem *item=new QGraphicsRectItem(QRectF(0,0,60,60));
    QPen pen;
    pen.setWidth(3);
    pen.setColor(QColor(rand()%256,rand()%256,rand()%256));
    item->setPen(pen);
    item->setBrush(QColor(rand()%256,rand()%256,rand()%256));
    item->setFlag(QGraphicsItem::ItemIsMovable);
    scene->addItem(item);
    item->setPos((rand()%int(scene->sceneRect().width()))-200,(rand()%int(scene->sceneRect().height()))-200);
}
void MainWindow::slotAddAlphaItem()//加入一个透明的蝴蝶图片
{
    QGraphicsPixmapItem *item=new QGraphicsPixmapItem(QPixmap("image.png"));
    item->setFlag(QGraphicsItem::ItemIsMovable);
    scene->addItem(item);
    item->setPos((rand()%int(scene->sceneRect().width()))-200,(rand()%int(scene->sceneRect().height()))-200);
}
void MainWindow::slotAddFlashItem()
{
    FlashItem *item=new FlashItem;
    scene->addItem(item);
    item->setPos((rand()%int(scene->sceneRect().width()))-200,(rand()%int(scene->sceneRect().height()))-200);
}

 void MainWindow::slotAddAnimItemAct()//实现星星移动
{
     StartIterm *item=new StartIterm;
    QGraphicsItemAnimation *anim=new QGraphicsItemAnimation;
     anim->setItem(item);
    /*QTimeLine *timeLine = new QTimeLine(4000); - 创建了一个时间线对象 timeLine，表示一个持续时间为 4000 毫秒（4 秒）的时间线。
     timeLine->setEasingCurve(QEasingCurve::OutSine); - 设置了时间线的缓动曲线为 OutSine 曲线，
     这个曲线用于控制动画的变化速度，使得动画的运动更加平滑自然。
    timeLine->setLoopCount(0); - 设置了时间线的循环次数为 0，表示动画不循环播放，播放完成后停止。
     anim->setTimeLine(timeLine); - 将时间线对象设置给了动画 anim，这样动画就与时间线关联起来了。
    int y = (rand() % 400) - 200; - 随机生成了一个 -200 到 200 之间的整数值，用于确定动画对象的起始纵坐标。
    for(int i = 0; i < 400; i++) { anim->setPosAt(i / 400.0, QPointF(i - 200, y)); } -
    循环设置了动画对象 anim 在时间线中不同时间点的位置。这里设置了从左到右的线性运动，每隔 1/400 秒（即 0.0025 秒）更新一次位置。
    因为时间线的持续时间为 4 秒，所以循环了 400 次。
    timeLine->start(); - 启动了时间线，开始播放动画。
    scene->addItem(item); - 将动画对象 item 添加到图形场景中，以便显示。
    综上所述，这段代码实现了一个在水平方向上从左到右匀速移动的动画效果，持续时间为 4 秒，运动的曲线为 OutSine 曲线.*/

    QTimeLine *timeLine=new QTimeLine(4000);
    timeLine->setEasingCurve(QEasingCurve::OutSine);
    timeLine->setLoopCount(1);//设置循环次数
    anim->setTimeLine(timeLine);
    int y=(rand()%400)-200;
    for(int i=0;i<400;i++)
    {
        anim->setPosAt(i/400.0,QPointF(i-200,y));
    }
    timeLine->start();
    scene->addItem(item);
}
